﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

#region Usings

using System;
using System.Collections.Generic;
using System.Linq;
using ScrumTable.Common.Collections;

#endregion

namespace ScrumTable.DL.Data.Generic.Cache
{
    /// <summary>
    /// This class wraps a team foundation identity instance.
    /// </summary>
    public class CacheMember : CacheElementBase
    {
        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------

        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------

        /// <summary>
        /// Gets the name which is used to reference this element from other
        /// CacheElements.
        /// </summary>
        public override string ReferenceName
        {
            get { return DisplayName; }
        }

        /// <summary>
        /// Gets the domain of the user.
        /// </summary>
        public string Domain
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the account name of the user.
        /// </summary>
        public string AccountName
        {
            get; private set;
        }

        /// <summary>
        /// Gets the underlying display name.
        /// </summary>
        public string DisplayName
        {
            get; private set;
        }

        /// <summary>
        /// Gets the underlying mail address.
        /// </summary>
        public string MailAddress { get; private set; }

        /// <summary>
        /// Gets the underlying display name.
        /// </summary>
        public Uri PictureUrl { get; set; }

        /// <summary>
        /// Returns true if the current member is able to login.
        /// </summary>
        public bool HasLogInData { get; private set; }

        /// <summary>
        /// Gets the display name of the assigned teams.
        /// </summary>
        public IEnumerable<string> Teams
        {
            get;
            private set;
        }

        /// <summary>
        /// Resolves a team ids to a full key chain (internal id).
        /// </summary>
        /// <remarks>This method will result in no action if the member is disconnected from a data context (e.g. a work item clone).</remarks>
        /// <returns>Returns internal key chains of the teams or an empty key chain enum if it could not be found.</returns>
        public ValueChain<string> AssignedToTeamChains
        {
            get
            {
                if (Project == null)
                {
                    return ValueChain<string>.Empty;
                }

                return new MultiValueChain<string>(
                    from cacheTeam in AssignedToTeams
                    select new ValueChain<string>(Project.UniqueId, cacheTeam.UniqueId));
            }
        }

        /// <summary>
        /// Resolves a member display name as object to a key chain (internal id).
        /// </summary>
        /// <returns>Returns internal key chain of the member or an empty key chain if it could not be found.</returns>
        public IEnumerable<CacheTeam> AssignedToTeams
        {
            get
            {
                if (Project == null) // clones are not associated to a project; currently not supported
                {
                    return new CacheTeam[0];
                }

                return Teams
                    .Select(teamUniqueId => Project.Teams.TryGetBy(t => t.ReferenceName == teamUniqueId))
                    .Where(team => team != null);
            }
        }

        #endregion

        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------

        /// <summary>
        /// Creates a new CacheMember instance. This constructor is used in
        /// the current library only.
        /// </summary>
        internal CacheMember(
            string uniqueId,
            double orderIndex,
            string displayName,
            string mailAddress,
            string accountName,
            string domain,
            string backEndId,
            bool hasLogInData,
            IEnumerable<string> teams)
            : base(uniqueId, CacheIdentity.DefaultId, displayName, CacheIdentity.DefaultRevision, orderIndex)
        {
            DisplayName = (displayName ?? string.Empty);
            MailAddress = (mailAddress ?? string.Empty);
            Domain = (domain ?? string.Empty);
            AccountName = (accountName ?? string.Empty);
            BackEndId = backEndId;
            HasLogInData = hasLogInData;
            Teams = teams ?? new string[0];
        }

        #endregion

        #region Methods
        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------

        /// <summary>
        /// Creates a new clone instance of the current object.
        /// </summary>
        /// <returns>Returns the created clone instance.</returns>
        protected override CacheElementBase CreateCloneInstance()
        {
            return new CacheMember(
                UniqueId,
                OrderIndex,
                DisplayName,
                MailAddress,
                AccountName,
                Domain,
                BackEndId,
                HasLogInData,
                Teams);
        }

        #endregion

        #region Events
        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------

        #endregion
    }
}